﻿using Common.Communication;
using Common.Device.DeviceDb;
using Common.Device.Enums;
using Common.Device.Interfaces;
using Common.Device.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace AnGuiYi.JueYuanNaiYa
{
    public class AT686SerialPort : SerialPortBase, IJueYuanNaiYa
    {
        public string Name { get; set; }
        public AT686SerialPort(UseDevice device) : base(device.port, Convert.ToInt32(device.parameter), timeout: 1000)
        {
            Name = device.name;
        }

        public Result<List<JueYuanNaiYaResult>> SetTest(Common.Device.Models.JueYuanNaiYa parameter)
        {
            lock (this)
            {
                var result = new Result<List<JueYuanNaiYaResult>>(new List<JueYuanNaiYaResult>());
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"设置蜂鸣器{false}");
                write = Write(CmdSetBeep("OFF"));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置蜂鸣器失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                //发送指令并返回
                read = WriteThenRead(CmdGetBeep);
                if (!read.IsSucceed || !read.Value.Contains("OFF"))
                {
                    result.IsSucceed = false;
                    result.Err = "设置蜂鸣器失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "设置蜂鸣器成功");
                AppendInfo(Name, $"新增测试方案");
                write = Write(CmdNew);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "新增测试方案失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetStep);
                if (!read.IsSucceed || !read.Value.Contains(CmdNewOk))
                {
                    result.IsSucceed = false;
                    result.Err = "新增测试方案失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置测试参数");
                AppendInfo(Name, $"步骤检查1");
                read = WriteThenRead(CmdGetStep);
                if (!read.IsSucceed || !read.Value.Contains("TOTAL"))
                {
                    result.IsSucceed = false;
                    result.Err = "步骤检查失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                if (Convert.ToInt32(read.Value.Split('-')[1].Replace("TOTAL", "").Trim()) < 1)
                {
                    AppendInfo(Name, $"新增步骤{1}");
                    write = Write(CmdInsertStep);
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "新增步骤失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    //发送指令并返回
                    read = WriteThenRead(CmdGetBeep);
                    if (!read.IsSucceed || !read.Value.Contains("STEP " + 1 + " - TOTAL " + 1))
                    {
                        result.IsSucceed = false;
                        result.Err = "新增步骤失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                }
                string type = "";
                switch (parameter.mode)
                {
                    case AnGuiYiEnum.TestMode.绝缘电阻:
                        type = "IR";
                        break;
                    case AnGuiYiEnum.TestMode.直流耐压:
                        type = "DCW";
                        break;
                    case AnGuiYiEnum.TestMode.交流耐压:
                        type = "ACW";
                        break;
                    default:
                        break;
                }
                AppendInfo(Name, $"设置测试类型{type}");
                write = Write(CmdType(type, 1));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置测试类型失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                //发送指令并返回
                read = WriteThenRead(CmdGetType(1));
                if (!read.IsSucceed || !read.Value.Contains(type))
                {
                    result.IsSucceed = false;
                    result.Err = "设置测试类型失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                if (parameter.mode == AnGuiYiEnum.TestMode.交流耐压)
                {
                    AppendInfo(Name, $"设置频率{parameter.电压频率}Hz");
                    write = Write(CmdFreq(parameter.电压频率, 1));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置频率失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetFreq(1));
                    if (!read.IsSucceed || !int.TryParse(read.Value, out int va) || va != parameter.电压频率)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置频率失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                }
                if (parameter.mode == AnGuiYiEnum.TestMode.交流耐压 || parameter.mode == AnGuiYiEnum.TestMode.直流耐压)
                {
                    AppendInfo(Name, $"设置电弧{parameter.电弧值}");
                    write = Write(CmdArc(parameter.电弧值, 1));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电弧失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetArc(1));
                    if (parameter.电弧值 > 0)
                    {
                        if (!read.IsSucceed || !double.TryParse(read.Value.Replace("LEVEL", ""), out double val) || val != parameter.电弧值)
                        {
                            result.IsSucceed = false;
                            result.Err = "设置电弧失败";
                            AppendTip(Name, result.Err);
                            return result.EndTime();
                        }
                    }
                    else
                    {
                        if (!read.IsSucceed || !read.Value.Contains("OFF"))
                        {
                            result.IsSucceed = false;
                            result.Err = "设置电弧失败";
                            AppendTip(Name, result.Err);
                            return result.EndTime();
                        }
                    }
                }
                AppendInfo(Name, $"设置电压{parameter.电压值}kV");
                write = Write(CmdSetVol(parameter.电压值, 1));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetVol(1));
                if (!read.IsSucceed || !double.TryParse(read.Value.Replace("KV",""), out double v) || v != parameter.电压值)
                {
                    result.IsSucceed = false;
                    result.Err = "设置电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置上升时间{parameter.上升时间}s");
                write = Write(CmdUpTime(parameter.上升时间, 1));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置上升时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetUpTime(1));
                if (!read.IsSucceed || !double.TryParse(read.Value.Replace("s", ""), out double ut) || ut != parameter.上升时间)
                {
                    result.IsSucceed = false;
                    result.Err = "设置上升时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置保持时间{parameter.测试时间}s");
                write = Write(CmdKeepTime(parameter.测试时间, 1));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置保持时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetKeepTime(1));
                if (!read.IsSucceed || !double.TryParse(read.Value.Replace("s", ""), out double kt) || kt != parameter.测试时间)
                {
                    result.IsSucceed = false;
                    result.Err = "设置保持时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置下降时间{parameter.下降时间}s");
                write = Write(CmdDownTime(parameter.下降时间, 1));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置下降时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetDownTime(1));
                if (!read.IsSucceed || !double.TryParse(read.Value.Replace("s", ""), out double dt) || dt != parameter.下降时间)
                {
                    result.IsSucceed = false;
                    result.Err = "设置下降时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置上限{parameter.上限值}");
                write = Write(CmdMax(parameter.上限值 ?? 0.0, 1));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置上限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetMax(1));
                if (parameter.上限值 == null && (!read.IsSucceed || !read.Value.Contains("OFF")))
                {
                    result.IsSucceed = false;
                    result.Err = "设置上限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                if (parameter.上限值!=null&&(!read.IsSucceed || !double.TryParse(read.Value.Trim().Substring(0,read.Value.Trim().Length-2), out double ma) || ma != parameter.上限值))
                {
                    result.IsSucceed = false;
                    result.Err = "设置上限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置下限{parameter.下限值}");
                write = Write(CmdMin(parameter.下限值 ?? 0.0, 1));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置下限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetMin(1));
                if (parameter.下限值 == null && (!read.IsSucceed || !read.Value.Contains("OFF")))
                {
                    result.IsSucceed = false;
                    result.Err = "设置上限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                if (parameter.下限值 != null && (!read.IsSucceed || !double.TryParse(read.Value.Trim().Substring(0, read.Value.Trim().Length - 2), out double mi) || mi != parameter.下限值))
                {
                    result.IsSucceed = false;
                    result.Err = "设置下限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置测试参数成功");
                AppendInfo(Name, $"开始测试");
                write = Write(CmdStart);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "开始测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"开始测试");
                write = Write(CmdFetchAuto);
                DateTime testTime = DateTime.Now.AddSeconds(parameter.上升时间+parameter.测试时间+parameter.下降时间 + 5);
                string r = "";
                while (string.IsNullOrEmpty(r)||r.Contains("0.000,PASS") && DateTime.Now < testTime)
                {
                    read = WriteThenRead(CmdFetch,wait:500);
                    //M1,ACW,Pass,0.01,0.000,5.0,1
                    r = read.Value?.Trim();
                    if (Common.Device.DeviceService.IsStop)
                    {
                        Write(CmdStop);
                        result.IsSucceed = false;
                        result.Err = "停止测试";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                }
                //返回值为空
                if (string.IsNullOrEmpty(r)||!r.Contains(";"))
                {
                    Write(CmdStop);
                    result.IsSucceed = false;
                    result.Err = "返回超时";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                // 解析测试结果 IR,0.050kV,34.59MΩ,PASS;ACW,0.050kV,0.000mA,PASS; 
                var str = r.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var item in str)
                {
                    string[] str2 = item.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    JueYuanNaiYaResult jueYuanNai = new JueYuanNaiYaResult()
                    {
                        type = str2[0],
                        value = str2[1] + "," + str2[2],
                        isPass = item.Contains("PASS"),
                    };
                    result.Value.Add(jueYuanNai);
                    AppendResult(Name, item);
                }
                result.IsSucceed = result.Value.Count(o => o.isPass == false) == 0;
                if (!result.IsSucceed)
                    result.Err = "测试未通过";
                return result.EndTime();
            }

        }


        public Result<bool> StopTest()
        {
            lock (this)
            {
                Result<bool> result = new Result<bool>();
                AppendInfo(Name, $"停止测试");
                List<string> temps = new List<string>();
                var write = Write(CmdStop);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "停止测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"停止测试成功");
                return result.EndTime();
            }
        }

        public double IrVolMin = 0.05f;
        public double IrVolMax = 1;
        public double TimeMin = 0.1f;
        public double TimeMax = 999.9f;
        public double IrMin = 0.1f;
        public double IrMax = 10000;
        public double DcwVolMin = 0.05f;
        public double DcwVolMax = 6f;
        public double DcwMin = 0.001f;
        public double DcwMax = 5;
        public double AcwVolMin = 0.05f;
        public double AcwVolMax = 1f;
        public double AcwMin = 0.0001f;
        public double AcwMax = 5;
        string Id => "*IDN?\n"; 
        string CmdNew=>":FUNC:SOUR:STEP:NEW\n"; 
        string CmdNewOk => "STEP 1 - TOTAL 1"; 
        string CmdInsertStep => ":FUNC:SOUR:STEP:INS\n";
        string CmdGetStep => ":FUNC:SOUR:STEP?\n";
        string CmdSetBeep(string beep) { return ":SYST:BEEP " + beep + "\n"; }
        string CmdGetBeep => ":SYST:BEEP?\n";   
        string CmdSetVol(double vol, int step) { return ":FUNC:SOUR:STEP" + step + ":VOLT " + vol + "\n"; }
        string CmdGetVol(int step) { return ":FUNC:SOUR:STEP" + step + ":VOLT?\n"; }
        string CmdUpTime(double upTime, int step) { return ":FUNC:SOUR:STEP" + step + ":RTIM " + upTime + "\n"; }
        string CmdGetUpTime(int step) { return ":FUNC:SOUR:STEP" + step + ":RTIM?\n"; }
        string CmdKeepTime(double keepTime, int step) { return ":FUNC:SOUR:STEP" + step + ":TTIM " + keepTime + "\n"; }
        string CmdGetKeepTime(int step) { return ":FUNC:SOUR:STEP" + step + ":TTIM?\n"; }
        string CmdDownTime(double downTime, int step) { return ":FUNC:SOUR:STEP" + step + ":FTIM " + downTime + "\n"; }
        string CmdGetDownTime(int step) { return ":FUNC:SOUR:STEP" + step + ":FTIM?\n"; }
        string CmdType(string type, int step) { return ":FUNC:SOUR:STEP" + step + ":TYPE " + type + "\n"; }
        string CmdGetType(int step) { return ":FUNC:SOUR:STEP" + step + ":TYPE?\n"; }
        string CmdFreq(int freq, int step) { return ":FUNC:SOUR:STEP" + step + ":FREQ " + freq + "\n"; }
        string CmdGetFreq(int step) { return ":FUNC:SOUR:STEP" + step + ":FREQ?\n"; }
        string CmdArc(double arc, int step) { return ":FUNC:SOUR:STEP" + step + ":ARC " + arc + "\n"; }
        string CmdGetArc(int step) { return ":FUNC:SOUR:STEP" + step + ":ARC?\n"; }
        string CmdMax(double max, int step) { return ":FUNC:SOUR:STEP" + step + ":UPPER " + max + "\n"; }
        string CmdGetMax(int step) { return ":FUNC:SOUR:STEP" + step + ":UPPER?\n"; }
        string CmdMin(double min, int step) { return ":FUNC:SOUR:STEP" + step + ":LOWER " + min + "\n"; }
        string CmdGetMin(int step) { return ":FUNC:SOUR:STEP" + step + ":LOWER?\n"; }
        string CmdFetchAuto => ":FETC:AUTO ON\n";
        string CmdGetFetchAuto => ":FETC:AUTO?\n";
        string CmdFetch => ":FETC?\n";
        string CmdStart => ":FUNC:START\n";
        string CmdStop => ":FUNC:STOP\n";
    }
}
